package com.jt.deepSeaMain;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.config.TimingConfig;
import com.jt.controller.DeepSeaHttpController;
import com.jt.dto.CollectParamsDto;
import com.jt.mapper.TimingMapper;
import com.jt.pojo.People;
import com.jt.pojo.PeoplePass;
import com.jt.pojo.Result;
import com.jt.pojo.Timing;
import com.jt.service.PeoplePassService;
import com.jt.service.PeopleService;
import com.mysql.cj.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.method.P;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.sql.Savepoint;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
@Slf4j
public class DeepPeopleTaskService extends TimingConfig {

    @Value("${task.people.switch}")
    private Boolean peopleSwitch;


    @Value("${task.people.cron}")
    private String peopleCron;


    @Value("${task.people.startTime}")
    private String startTime;

    @Autowired
    private DeepSeaHttpController deepSeaHttpController;

    @Autowired
    private HttpURLConnectionGetResult httpURLConnectionGetResult;

    @Autowired
    private TimingMapper timingMapper;

    @Autowired
    private PeopleService peopleService;

    @Autowired
    private PeoplePassService peoplePassService;

    @Override
    protected Boolean getSwitch() {
        return peopleSwitch;
    }

    @Override
    protected String getCron() {
        return peopleCron;
    }

    @Override
    protected void processTask() throws IOException {
        try {
            log.info("<<<<<<<<<<<<<start人脸人体定时任务>>>>>>>");
            //1:人脸face
            CollectParamsDto collectParamsDtoFace = new CollectParamsDto();
            collectParamsDtoFace.setPage(1);
            collectParamsDtoFace.setPageSize(100);
            collectParamsDtoFace.setSourceId("10174,7115");
            collectParamsDtoFace.setTargetType("face");
            collectParamsDtoFace.setRelative("body");
            /*开始时间，需要查库拿到最后入库的时间data*/
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String systemTime = sdf.format(new Date());
            /*统一接口调用*/
            if (systemTime.compareTo(startTime) < 0) {
                throw new RuntimeException("人脸定时器执行时间小于系统默认开始时间");
            } else {
                getCollectListAndSaveAll(startTime, systemTime, collectParamsDtoFace);
            }
        } catch (Exception e) {
            log.error(e.toString());
        }
    }


    /*统一去存入定时任务的开始结束和状态以及人抓入库和定时器时间入库*/
    public void getCollectListAndSaveAll(String startTime, String systemTime, CollectParamsDto collectParamsDtoFace) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<People> peopleList = null;
        List<String> timeList = new ArrayList<>();
        String tid = UUID.randomUUID().toString().substring(8);
        /*结束时间，拿到系统前一分钟时间*/
        String beforeTime = getBeForTime(systemTime);
        try {
            /*如果定时表中没有数据，是第一次查，我们就取全局设定的开始时间,反之取最后查出来的时间*/
            Timing timingOne = timingMapper.selectOne(new QueryWrapper<Timing>().eq("type", "face").orderByDesc("end_time").last("limit 1"));
            Timing timing = new Timing();
            timing.setId(UUID.randomUUID().toString().substring(10));
            timing.setTid(tid);
            timing.setType("face");
            timing.setState("0");
            if (Objects.isNull(timingOne)) {
                /*定时任务开始之前存库一次*/
                timing.setStartTime(startTime);
                timing.setEndTime(beforeTime);
                timingMapper.insert(timing);/*0执行中，1异常,2完成*/
                timeList.add(startTime);
                timeList.add(beforeTime);
                collectParamsDtoFace.setTimeList(timeList);
                /*调用采集接口*/
                retrieveCollect(collectParamsDtoFace, timing);
            } else {
                /*定时任务开始之前存库一次*/
                String endTime = timingOne.getEndTime();
                timing.setStartTime(endTime);
                timing.setEndTime(beforeTime);
                timingMapper.insert(timing);/*0执行中，1异常,2完成*/
                timeList.add(endTime);
                timeList.add(beforeTime);
                collectParamsDtoFace.setTimeList(timeList);
                /*调用采集接口*/
                retrieveCollect(collectParamsDtoFace, timing);
            }
        } catch (Exception e) {
            log.error(e.toString());
        }

    }

    public void retrieveCollect(CollectParamsDto collectParamsDtoFace, Timing timing) {
        List<People> peopleList = null;
        CollectParamsDto collectParamsDto = null;
        try {
            boolean isAndNo = true;
            String jsonStr = "";
            while (isAndNo) {
                if (StringUtils.isNullOrEmpty(jsonStr)) {
                    /*第一次请求*/
                    jsonStr = httpURLConnectionGetResult.getCollectList(collectParamsDtoFace);
                    System.out.println("第一次请求采集数据结果====={}" + jsonStr);
                } else {
                    /*不是第一次访问*/
                    JSONObject jsonObject = JSON.parseObject(jsonStr);
                    String partitionId = jsonObject.get("partitionId").toString();
                    String sequence = jsonObject.get("sequence").toString();
                    collectParamsDto.setPartitionId(partitionId);
                    collectParamsDto.setSequence(sequence);
                    collectParamsDto.setTargetType(collectParamsDtoFace.getTargetType());
                    collectParamsDto.setTimeList(collectParamsDtoFace.getTimeList());
                    collectParamsDto.setPageSize(collectParamsDtoFace.getPageSize());
                    collectParamsDto.setRelative(collectParamsDtoFace.getRelative());
                    jsonStr = httpURLConnectionGetResult.getCollectList(collectParamsDto);
                }
                JSONObject jsonObject = JSON.parseObject(jsonStr);
                Integer code = Integer.getInteger(jsonObject.get("code").toString());
                if (code == 200) {
                    System.out.println("等于200");
                    /*保存结果*/
                    savePeopleAndPeoplePass(jsonObject);
                    String faces = jsonObject.get("faces").toString();
                    peopleList = JSON.parseArray(faces, People.class);
                    /*从写collectParamsDtoFace入参*/
                    if (peopleList.size() < collectParamsDtoFace.getPageSize()) {
                        /*如果小于则说明已经查完了*/
                        timing.setPartitionId(jsonObject.get("partitionId").toString());
                        timing.setSequence(jsonObject.get("sequence").toString());
                        timing.setState("1");
                        timingMapper.insert(timing);
                        log.error("完成");
                        break;
                    } else {
                        /*在进行中*/
                        System.out.println("不等于200");
                        timing.setPartitionId(jsonObject.get("partitionId").toString());
                        timing.setSequence(jsonObject.get("sequence").toString());
                        timing.setState("0");
                        timingMapper.insert(timing);
                        log.error("进行中");
                    }
                } else {
                    /*失败了*/
                    timing.setPartitionId(jsonObject.get("partitionId").toString());
                    timing.setSequence(jsonObject.get("sequence").toString());
                    timing.setState("2");
                    timingMapper.insert(timing);
                    log.error("采集接口连环调用失败了");
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    ;

    public void savePeopleAndPeoplePass(JSONObject jsonObject) {
        System.out.println("进入savePeopleAndPeoplePass方法，数据result===" + jsonObject);
        List<People> peopleList = null;
        List<PeoplePass> peoplePassList = null;
        List<People> newPeopleList = new ArrayList<>();
        List<PeoplePass> newPeoplePassList = new ArrayList<>();
        try {
            /*人脸数据*/
            String faces = jsonObject.get("faces").toString();
            peopleList = JSON.parseArray(faces, People.class);
            peopleList.forEach(onePeople -> {
                onePeople.setId(UUID.randomUUID().toString().substring(9));
                newPeopleList.add(onePeople);
            });
            boolean isAndTruePeople = peopleService.saveBatch(newPeopleList);
            if (!isAndTruePeople) {
                log.error("人脸数据保存失败");
            } else {
                log.info("人脸数据保存成功");
            }
            /*人体数据*/
            String bodies = jsonObject.get("bodies").toString();
            peoplePassList = JSON.parseArray(bodies, PeoplePass.class);
            peoplePassList.forEach(PeoplePass -> {
                PeoplePass.setId(UUID.randomUUID().toString());
                newPeoplePassList.add(PeoplePass);
            });
            boolean isAndTruePeoplePass = peoplePassService.saveBatch(newPeoplePassList);
            if (!isAndTruePeoplePass) {
                log.error("人体数据保存失败");
            } else {
                log.info("人体数据保存成功");
            }
        } catch (Exception e) {
            log.error("savePeopleAndPeoplePass方法中存库异常为:{}", e.toString());
            e.printStackTrace();
        }
    }

    public String getBeForTime(String systemTime) {
        String resultTime = "";
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 将传入进来的时间转化为"yyyy-MM-dd HH:mm:ss"格式（格式可根据实际情况更改）
            Date startTime = sdf.parse(systemTime);
            System.out.println("系统时间==" + systemTime);
            // 将传入进来的时间转化为时间戳 ，然后再当前时间戳上加60000ms（1min=60000ms）
            long endTimeStamp = startTime.getTime() - 60000 * 2;
            // 转化计算得到的时间戳
            String endDateTemp = sdf.format(endTimeStamp);
            Date endTime = sdf.parse(endDateTemp);
            resultTime = sdf.format(endTime);
        } catch (Exception e) {
            log.error("获取系统前一分钟时间异常");
            e.printStackTrace();
        }
        return resultTime;
    }


}
